package com.cheerscpl.service.impl;

import com.cheerscpl.TaskQueue;
import com.cheerscpl.TaskQueue4Redis;
import com.cheerscpl.protocol.Channels;
import com.cheerscpl.service.TaskQueueService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static com.cheerscpl.Constants.DEVICESET;

/**
 * Created by chenpuliang on 2017/6/4.
 */
@Service
public class TaskQueueServiceImpl implements TaskQueueService {

    private static final Logger logger = LoggerFactory.getLogger(TaskQueueServiceImpl.class);

    //TODO 可考虑guava cache实现
    private static Map<String, TaskQueue> queueMap = new ConcurrentHashMap<>();

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void initQueue() {
        for(String devId : getCurrentKeys()){
            if(queueMap.get(devId) == null){
                queueMap.put(devId, new TaskQueue4Redis(devId));
            }
        }
        refreshQueue();
        logger.debug("taskQueue init success.");
    }

    /**
     * 获取当前连接中的设备
     * @return
     */
    private Set<String> getCurrentKeys() {
        return Channels.getMapKeys();
    }

    @Override
    public void refreshQueue() {
        Set<String> deviceSet = this.getQueueSetFromRedis();
        if(null == deviceSet){
            deviceSet = new HashSet<>();
        }
        for(Map.Entry<String, TaskQueue> entry : queueMap.entrySet()){
            if(!deviceSet.contains(entry.getKey())){
                deviceSet.add(entry.getKey());
            }
        }
        redisTemplate.delete(DEVICESET);
        redisTemplate.opsForSet().add(DEVICESET, deviceSet);
    }

    @Override
    public void addQueue(TaskQueue taskQueue) {
        if(taskQueue != null){
            if(queueMap.get(taskQueue.getName()) == null){
                queueMap.put(taskQueue.getName(), taskQueue);
            }
            refreshQueue();
            logger.debug("add queue: {} success.", taskQueue.getName());
        }
    }

    @Override
    public TaskQueue getTaskQueue(String name) {
        return queueMap.get(name);
    }

    @Override
    public Set<TaskQueue> getQueueSet() {
        Set<TaskQueue> queueSet = new HashSet<>();
        for(Map.Entry<String, TaskQueue> entry : queueMap.entrySet()){
            queueSet.add(entry.getValue());
        }
        return queueSet;
    }

    /**
     * 获取redis中总的设备队列
     * @return
     */
    private Set<String> getQueueSetFromRedis() {
        return redisTemplate.opsForSet().members(DEVICESET);
    }
}
